package com.jh.paymentchannel.service.impl;

import cn.jh.common.exception.ServiceException;
import cn.jh.common.utils.ChannelType;
import cn.jh.common.utils.DateUtil;
import com.jh.paymentchannel.pojo.enums.PayStatus;
import com.jh.paymentchannel.pojo.enums.PayType;
import com.jh.paymentchannel.pojo.freeQuick.FreeQuickWithdrawTemp;
import com.jh.paymentchannel.repository.freeQuick.FreeQuickWithdrawTempRepository;
import com.jh.paymentchannel.service.freeQuick.FreeQuickWithdrawTempService;
import net.sf.json.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author zhugu
 * @version 1.0
 * @Date 2019/1/3 17:11
 */
@Service("freeQuickWithdrawTempService")
public class FreeQuickWithdrawTempServiceImpl implements FreeQuickWithdrawTempService {
    private static final Logger log = LoggerFactory.getLogger(FreeQuickWithdrawTempServiceImpl.class);

    private final FreeQuickPayServiceImpl freeQuickPayServiceImpl;
    private final FreeQuickWithdrawTempRepository freeQuickWithdrawTempRepository;

    public FreeQuickWithdrawTempServiceImpl(FreeQuickPayServiceImpl freeQuickPayServiceImpl,
                                            FreeQuickWithdrawTempRepository freeQuickWithdrawTempRepository) {
        this.freeQuickPayServiceImpl = freeQuickPayServiceImpl;
        this.freeQuickWithdrawTempRepository = freeQuickWithdrawTempRepository;
    }

    @Override
    public Map<String, Object> cardlessTransactionPage(String requestNo, String payStatus, String payType, String startTime, String endTime, Pageable pageable) throws ServiceException {
        Map<String, Object> resMap = new LinkedHashMap<>();
        List<Map<String, Object>> list = new ArrayList<>();

        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime) && startTime.length() == 10 && endTime.length() == 10) {
            startTime = startTime + " 00:00:00";
            endTime = endTime + " 23:59:59";
        }

        Page<FreeQuickWithdrawTemp> freeQuickWithdrawTempPage = freeQuickWithdrawTempRepository.findAll(where(requestNo, payStatus, payType, startTime, endTime), pageable);
        List<FreeQuickWithdrawTemp> content = freeQuickWithdrawTempPage.getContent();

        if (content.size() == 0) {
            resMap.put("content", content);
        } else {
            StringBuilder userIdSb = new StringBuilder();
            for (FreeQuickWithdrawTemp order : freeQuickWithdrawTempPage) {
                if (StringUtils.isNotBlank(order.getUserId())) {
                    userIdSb.append(order.getUserId()).append(",");
                }
            }

            JSONArray userArray = new JSONArray();
            if (userIdSb.length() > 0) {
                userArray = freeQuickPayServiceImpl.getUserPhone(userIdSb.substring(0, userIdSb.length() - 1));
            }

            for (FreeQuickWithdrawTemp freeQuickWithdrawTemp : content) {
                Map<String, Object> map = new LinkedHashMap<>();

                int id = freeQuickWithdrawTemp.getId();
                String userId = freeQuickWithdrawTemp.getUserId();
                String channelDesc = ChannelType.of(Integer.parseInt(freeQuickWithdrawTemp.getChannelId())).getDesc();
                requestNo = freeQuickWithdrawTemp.getRequestNo();
                String merchantNo = freeQuickWithdrawTemp.getMerchantNo();
                BigDecimal inAmount = freeQuickWithdrawTemp.getInAmount();
                String amount = freeQuickWithdrawTemp.getAmount();
                payStatus = Objects.requireNonNull(PayStatus.of(freeQuickWithdrawTemp.getPayStatus())).getDesc();
                Date updateTime = freeQuickWithdrawTemp.getUpdateTime();
                Date createTime = freeQuickWithdrawTemp.getCreateTime();
                payType = Objects.requireNonNull(PayType.of(freeQuickWithdrawTemp.getPayType())).getDesc();

                map.put("id", id);
                freeQuickPayServiceImpl.phoneMap(userArray, map, userId, "phone");
                map.put("channelDesc", channelDesc);
                map.put("requestNo", requestNo);
                map.put("merchantNo", merchantNo);
                map.put("inAmount", inAmount);
                map.put("amount", amount);
                map.put("payStatus", payStatus);
                map.put("updateTime", updateTime);
                map.put("createTime", createTime);
                map.put("payType", payType);

                list.add(map);
            }

            resMap.put("content", list);
        }

        resMap.put("first", freeQuickWithdrawTempPage.isFirst());
        resMap.put("last", freeQuickWithdrawTempPage.isLast());
        resMap.put("totalElements", freeQuickWithdrawTempPage.getTotalElements());
        resMap.put("totalPages", freeQuickWithdrawTempPage.getTotalPages());
        resMap.put("number", freeQuickWithdrawTempPage.getNumber());
        resMap.put("size", freeQuickWithdrawTempPage.getSize());
        resMap.put("sort", freeQuickWithdrawTempPage.getSort());
        resMap.put("numberOfElements", freeQuickWithdrawTempPage.getNumberOfElements());

        return resMap;
    }

    private Specification<FreeQuickWithdrawTemp> where(final String requestNo, final String payStatus, final String payType, final String startTime, final String endTime) {
        return (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(requestNo)) {
                predicates.add(criteriaBuilder.equal(root.<String>get("requestNo"), requestNo));
            }
            // 只显示成功的
            predicates.add(criteriaBuilder.equal(root.<String>get("payStatus"), "1"));

            if (StringUtils.isNotBlank(payType)) {
                predicates.add(criteriaBuilder.equal(root.<String>get("payType"), payType));
            }
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                predicates.add(criteriaBuilder.greaterThan(root.<Date>get("createTime"), DateUtil.getYYMMHHMMSSDateFromStr(startTime)));
                predicates.add(criteriaBuilder.lessThan(root.<Date>get("createTime"), DateUtil.getYYMMHHMMSSDateFromStr(endTime)));
            }
            return criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        };
    }
}
